package atpa.partial;

import java.util.Random;

public class ListaSmp {

    private Nod t;
    private Nod x;

    public ListaSmp(int[] val) {
        this.t = new Nod(val[0]);
        x = t;
        for (int i = 1; i < val.length; i++) {
            x.urm = new Nod(val[i]);
            x = x.urm;
        }
    }

    public ListaSmp(int nrElem, int min, int max) {
        Random seed = new Random();
        this.t = new Nod(seed.nextInt(max - min) + min);
        x = t;
        for (int i = 1; i < nrElem; i++) {
            x.urm = new Nod(seed.nextInt(max - min) + min);
            x = x.urm;
        }
    }

    public Nod getHead() {
        return this.t;
    }

    public void insertAtPoz(int poz, int val) {
        if (poz > this.count() || poz < 1) {
            System.out.println("ERROR: Out_of_bounds");
        } else if (poz == 1) {
            Nod z = new Nod(val);
            z.urm = t;
            t = z;
        } else {
            x = this.t;
            for (int i = 1; i < poz - 1; i++) {
                x = x.urm;
            }
            Nod z = new Nod(val);
            z.urm = x.urm;
            x.urm = z;
        }
    }

    public void insertAfterPoz(int poz, int val) {
        if (poz > this.count() - 1 || poz < 1) {
            System.out.println("ERROR: Out_of_bounds");
        } else {
            x = this.t;
            for (int i = 1; i < poz; i++) {
                x = x.urm;
            }
            Nod z = new Nod(val);
            z.urm = x.urm;
            x.urm = z;
        }
    }

    public void insertBeforePoz(int poz, int val) {
        if (poz > this.count() + 1 || poz <= 1) {
            System.out.println("ERROR: Out_of_bounds");
        } else if (poz == 2) {
            Nod z = new Nod(val);
            z.urm = t;
            t = z;
        } else {
            x = this.t;
            for (int i = 1; i < poz - 2; i++) {
                x = x.urm;
            }
            Nod z = new Nod(val);
            z.urm = x.urm;
            x.urm = z;
        }
    }

    public void insertAfterVal(int valc, int val) {
        x = this.t;
        int i = 1;
        while (x != null) {
            if (x.val == valc) {
                insertAfterPoz(i, val);
                x = x.urm;
                i++;
            }
            x = x.urm;
            i++;
        }
    }

    public void insertBeforeVal(int valc, int val) {
        x = this.t;
        int i = 1;
        while (x != null) {
            if (x.val == valc) {
                Nod z = x;
                insertAtPoz(i, val);
                x = z;
                i++;
            }
            x = x.urm;
            i++;
        }
    }

    public void deleteAtPoz(int poz) {
        if (poz > this.count() || poz < 1) {
            System.out.println("ERROR: Out_of_bounds");
        } else if (poz == 1) {
            t = t.urm;
            x = t;
        } else {
            x = this.t;
            for (int i = 1; i < poz - 1; i++) {
                x = x.urm;
            }
            x.urm = x.urm.urm;
        }
    }

    public void deleteAfterPoz(int poz) {
        if (poz > this.count() - 2 || poz < 1) {
            System.out.println("ERROR: Out_of_bounds");
        } else {
            x = this.t;
            for (int i = 1; i < poz; i++) {
                x = x.urm;
            }
            x.urm = x.urm.urm;
        }
    }

    public void deleteBeforePoz(int poz) {
        if (poz > this.count() || poz <= 1) {
            System.out.println("ERROR: Out_of_bounds");
        } else if (poz == 2) {
            t = t.urm;
        } else {
            x = this.t;
            for (int i = 1; i < poz - 2; i++) {
                x = x.urm;
            }
            x.urm = x.urm.urm;
        }
    }

    public void deleteAfterVal(int valc) {
        x = this.t;
        int i = 1;
        while (x != null) {
            if (x.val == valc) {
                Nod z = x;
                deleteAfterPoz(i);
                x = z;
            }
            x = x.urm;
            i++;
        }
    }

    public void deleteBeforeVal(int valc) {
        x = this.t;
        int i = 1;
        while (x != null) {
            if (x.val == valc) {
                Nod z = x;
                deleteBeforePoz(i);
                x = z;
                i--;
            }
            x = x.urm;
            i++;
        }
    }

    public void deleteAtValue(int valc) {
        x = this.t;
        int i = 1;
        while (x != null) {
            if (x.val == valc) {
                deleteAtPoz(i);
                i--;
            }
            x = x.urm;
            i++;
        }
    }

    public void replaceAtValue(int valc, int val) {
        this.insertBeforeVal(valc, val);
        this.deleteAtValue(valc);
    }

    public void replaceAtPoz(int poz, int val) {
        this.insertAtPoz(poz, val);
        this.deleteAfterPoz(poz);
    }

    public void show() {
        x = this.t;
        int i = 1;
        int val_urm;
        do {
            if (x.urm == null) {
                val_urm = -1;
            } else {
                val_urm = x.urm.val;
            }
            System.out.println("Nod " + i + " val=" + x.val + " urm=" + val_urm);
            x = x.urm;
            i++;
        } while (x != null);
        System.out.println("-----------------");
    }

    public int count() {
        x = this.t;
        int i = 1;
        do {
            x = x.urm;
            i++;
        } while (x != null);
        return i;
    }

    public void bubbleSort() {
        boolean gasit = true;
        Nod asta;
        Nod next;
        int temp;
        while (gasit) {
            asta = t;
            next = t.urm;
            gasit = false;
            for (int i = 1; i < this.count() - 1; i++) {
                if (asta.val > next.val) {
                    temp = asta.val;
                    asta.val = next.val;
                    next.val = temp;
                    gasit = true;
                    break;
                }
                if (asta.urm != null) {
                    asta = asta.urm;
                    next = next.urm;
                }
            }
        }
    }

    public void bubbleSortNode() {
        boolean gasit = true;
        Nod prev;
        Nod asta;
        Nod next;
        while (gasit) {
            System.out.println("check 1");
            prev = t;
            asta = t.urm;
            next = asta.urm;
            gasit=false;
            for (int i = 1; i < this.count() - 2; i++) {
            System.out.println("prev= "+prev.val);
            System.out.println("asta= "+asta.val);
            System.out.println("next= "+next.val);
                System.out.println("fors");
                if (prev.val > asta.val) {
                    System.out.println("check if 1");
                    prev.urm = next;
                    asta.urm = prev;
                    t = asta;
                    gasit = true;
                    this.show();
                    break;
                }
                if (asta.val > next.val) {
                    System.out.println("check if 2");
                    prev.urm = next;
                    asta.urm = next.urm;
                    next.urm = asta;
                    gasit = true;
                    this.show();
                    break;
                }
                if (asta.urm != null) {
                    System.out.println("check if 3");
                    prev = prev.urm;
                    asta = asta.urm;
                    next = next.urm;
                }
            }
        }
    }
}
